package com.hjx.windowtool.video;

import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;

import javax.swing.JFrame;
import javax.swing.JSplitPane;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.UIManager;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hjx.windowtool.db.Tool;
import com.hjx.windowtool.util.MyAppender;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;

import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;

@Tool("生成预览图")
public class VideoPreviewApp {
	Logger LOGGER =LoggerFactory.getLogger(VideoPreviewApp.class);
	private JFrame frame;
	private JTextField txt_file;
	private JTextField txt_wsize;
	private JTextField txt_hsize;
	private JButton btn_create;
	private JTextArea txt_msg;
	private JTextField txt_ignoreTime;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
					VideoPreviewApp window = new VideoPreviewApp();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public VideoPreviewApp() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 724, 513);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(0.5);
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		frame.getContentPane().add(splitPane, BorderLayout.CENTER);

		JScrollPane scrollPane = new JScrollPane();
		splitPane.setRightComponent(scrollPane);

		txt_msg = new JTextArea();
		txt_msg.setWrapStyleWord(true);
		scrollPane.setViewportView(txt_msg);

		JPanel panel = new JPanel();
		splitPane.setLeftComponent(panel);
		panel.setLayout(null);

		JLabel label = new JLabel("文件");
		label.setBounds(10, 25, 72, 15);
		panel.add(label);

		txt_file = new JTextField();
		txt_file.setBounds(86, 22, 464, 21);
		panel.add(txt_file);
		txt_file.setColumns(10);
		
		DropTarget dropTarget = new DropTarget(txt_file, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetAdapter() {
			@Override
			public void drop(DropTargetDropEvent dtde) {
				try {
					if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
					    // 接收拖拽目标数据
					    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);

					    // 以文件集合的形式获取数据
					    List<File> files = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);

					    // 把文件路径输出到文本区域
					    if (files != null && files.size() > 0) {
					        StringBuilder filePaths = new StringBuilder();
					        for (File file : files) {
					            filePaths.append(";" + file.getAbsolutePath());
					        }
					        filePaths.deleteCharAt(0);
					        txt_file.setText(filePaths.toString());
					        dtde.dropComplete(true);
					    }
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}, true);


		JButton button = new JButton("选择");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser f=new JFileChooser();
				f.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
				f.setMultiSelectionEnabled(true);
				int showOpenDialog = f.showOpenDialog(frame);
				 if(showOpenDialog==JFileChooser.APPROVE_OPTION)
	                {
	                    File[] files=f.getSelectedFiles();
	                    StringBuffer sb=new StringBuffer();
	                    for (File file : files) {
	                    	sb.append(";");
	                    	sb.append(file.getAbsolutePath());
	                    }
	                    sb.deleteCharAt(0);
	                    txt_file.setText(sb.toString());
	                }
			}
		});
		button.setBounds(560, 21, 93, 23);
		panel.add(button);

		JLabel label_1 = new JLabel("预览图数量");
		label_1.setBounds(10, 60, 70, 15);
		panel.add(label_1);

		txt_wsize = new JTextField();
		txt_wsize.setText("6");
		txt_wsize.setBounds(86, 57, 66, 21);
		panel.add(txt_wsize);
		txt_wsize.setColumns(10);

		JLabel lblX = new JLabel("X");
		lblX.setBounds(156, 60, 12, 15);
		panel.add(lblX);

		txt_hsize = new JTextField();
		txt_hsize.setText("6");
		txt_hsize.setBounds(166, 57, 66, 21);
		panel.add(txt_hsize);
		txt_hsize.setColumns(10);

		btn_create = new JButton("生成");
		btn_create.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_create.setEnabled(false);
				createPreview();
			}
		});
		btn_create.setBounds(86, 88, 93, 23);
		panel.add(btn_create);
		
		JLabel label_2 = new JLabel("忽略开始时间");
		label_2.setBounds(252, 60, 79, 15);
		panel.add(label_2);
		
		txt_ignoreTime = new JTextField();
		txt_ignoreTime.setText("30");
		txt_ignoreTime.setBounds(341, 57, 66, 21);
		panel.add(txt_ignoreTime);
		txt_ignoreTime.setColumns(10);
		
		JLabel label_3 = new JLabel("秒");
		label_3.setBounds(414, 60, 54, 15);
		panel.add(label_3);
		MyAppender.list.add(new MyAppender.LogCallback() {
			
			@Override
			public void log(String s) {
				apend(s);
			}
		});
	}

	/**
	 * 
	 */
	public void createPreview() {
		new Thread(new Runnable() {
			public void run() {
				File file = new File(txt_file.getText());
				createPreviewAll(file);
				
				btn_create.setEnabled(true);
			}

			
		}).start();
	}
	protected void createPreviewAll(File file) {
		if (file.isDirectory()) {
			File[] listFiles = file.listFiles();
			for (File file2 : listFiles) {
				createPreviewAll(file2);
			}
		}else {
			String name = file.getName().toLowerCase();
			if (name.endsWith("mp4")||name.endsWith("mkv")||name.endsWith("wav")||name.endsWith("avi")||name.endsWith("flv")||name.endsWith("wmv")) {
				createPreview(file);
			}
		}
		
	}

	/**
	 * @param file
	 */
	public void createPreview(File file) {
		LOGGER.info("生成缩略图："+file);
		try (FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file.getAbsolutePath())) {
			ff.start();
			Java2DFrameConverter c = new Java2DFrameConverter();
			int w = Integer.valueOf(txt_wsize.getText());
			int h = Integer.valueOf(txt_hsize.getText());
			int startFrame=(int) (Integer.valueOf(txt_ignoreTime.getText())*ff.getFrameRate());
			int lengthInFrames = ff.getLengthInFrames()-startFrame;
			int temp = lengthInFrames / (w * h);
			int imageWidth = ff.getImageWidth();
			int imageHeight = ff.getImageHeight();
			LOGGER.info("LengthInFrames={},frameRate={},imageWidth={},imageHeight={}",ff.getLengthInFrames(),ff.getFrameRate(),imageWidth,imageHeight);
			BufferedImage convert = c.convert(ff.grabImage());
			BufferedImage img = new BufferedImage(imageWidth * w, imageHeight * h, convert.getType());

			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					int frame = i * w + j;
					LOGGER.info("获取第" + (frame * temp+startFrame) + "帧图片");
					ff.setFrameNumber(frame * temp+startFrame);
					BufferedImage convert2 = c.convert(ff.grabImage());
					img.getGraphics().drawImage(convert2, j * imageWidth, i * imageHeight, null);
				}
			}
			File file2 = new File(file.getParent(), file.getName().substring(0, file.getName().lastIndexOf(".")) + "_preview.jpg");
			LOGGER.info("正在写入图片" + file2);
			ImageIO.write(img, "jpg", new FileOutputStream(file2));
			LOGGER.info("生成缩略图完成");
		} catch (Exception e) {
			LOGGER.error("发生错误",e);
		} finally {
		}
	}

	void apend(String s) {
		txt_msg.append(s + "");
		int length = txt_msg.getText().length();
		txt_msg.select(length, length);
	}
}
